package Observer;

import java.util.ArrayList;
import java.util.List;

// 观察者接口
interface Observer {
    String getName();
    void setName(String name);
    void help(); // 援助盟友
    void beAttacked(AllyControlCenter acc); // 受到攻击
}

// 抽象盟友控制中心（主题/被观察者）
abstract class AllyControlCenter {
    protected String allyName; // 战队名称
    protected List<Observer> players = new ArrayList<>(); // 战队成员列表

    public void setAllyName(String allyName) {
        this.allyName = allyName;
    }

    public String getAllyName() {
        return this.allyName;
    }

    // 加入战队
    public void join(Observer obs) {
        System.out.println(obs.getName() + "加入" + this.allyName + "战队！");
        players.add(obs);
    }

    // 退出战队
    public void quit(Observer obs) {
        System.out.println(obs.getName() + "退出" + this.allyName + "战队！");
        players.remove(obs);
    }

    // 通知盟友的抽象方法
    public abstract void notifyObserver(String name);
}

// 具体盟友控制中心
class ConcreteAllyControlCenter extends AllyControlCenter {
    public ConcreteAllyControlCenter(String allyName) {
        System.out.println(allyName + "战队组建成功！");
        this.allyName = allyName;
    }

    // 实现通知方法
    @Override
    public void notifyObserver(String name) {
        System.out.println(this.allyName + "战队紧急通知，盟友" + name + "遭受敌人攻击！");
        // 遍历观察者集合，调用除了被攻击者的其他盟友的援助方法
        for (Observer obs : players) {
            if (!obs.getName().equalsIgnoreCase(name)) {
                obs.help();
            }
        }
    }
}

// 具体观察者类：玩家
class Player implements Observer {
    private String name;

    public Player(String name) {
        this.name = name;
    }

    @Override
    public String getName() {
        return this.name;
    }

    @Override
    public void setName(String name) {
        this.name = name;
    }

    // 援助盟友的具体实现
    @Override
    public void help() {
        System.out.println("坚持住，" + this.name + "来救你！");
    }

    // 遭受攻击的具体实现
    @Override
    public void beAttacked(AllyControlCenter acc) {
        System.out.println(this.name + "被攻击，向盟友求助！");
        acc.notifyObserver(this.name);
    }
}

// 测试类
public class ObserverPatternDemo {
    public static void main(String[] args) {
        // 创建一个战队控制中心
        AllyControlCenter acc = new ConcreteAllyControlCenter("复仇者联盟");

        // 创建四个玩家
        Observer player1 = new Player("钢铁侠");
        Observer player2 = new Player("美国队长");
        Observer player3 = new Player("雷神");
        Observer player4 = new Player("绿巨人");

        // 玩家加入战队
        acc.join(player1);
        acc.join(player2);
        acc.join(player3);
        acc.join(player4);

        System.out.println("----------------------");

        // 其中一个玩家受到攻击
        player1.beAttacked(acc);
    }
}
